import { ComponentClass } from 'react'
import Taro, { Component, Config } from '@tarojs/taro'
import { View, Image, Button } from '@tarojs/components'
import { connect } from '@tarojs/redux'

import bannerImg from '../../asset/images/step-apply-one/banner.jpg'
import { noConsole } from '../../config'
import ApplyFormItem from '../../model/apply-form'
import ApplyForm from '../../components/apply-form'

import './index.scss'
import { Utils } from '../../utils/utils';
import ProductUtils from '../../utils/product'
import { User as UserUtils } from '../../utils/user'


// const qqmapUtils = new QQmapUtils
const utils = new Utils()
const productUtils = new ProductUtils()
const userUtils = new UserUtils()

// #region 书写注意
// 
// 目前 typescript 版本还无法在装饰器模式下将 Props 注入到 Taro.Component 中的 props 属性
// 需要显示声明 connect 的参数类型并通过 interface 的方式指定 Taro.Component 子类的 props
// 这样才能完成类型检查和 IDE 的自动提示
// 使用函数模式则无此限制
// ref: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/20796
//
// #endregion

type PageStateProps = {
  form: ApplyFormItem[]
  formValue: any
}

type PageDispatchProps = {
  dispatchSave: (param: any) => void,
  dispatchGetCredit: (callback: Function) => void,
}

type PageOwnProps = {}

type PageState = {
  deposit: number,    // 贷款额度
}

type IProps = PageStateProps & PageDispatchProps & PageOwnProps

interface SetpApplyOne {
  props: IProps;
  state: PageState;
}

@connect(({ stepApplyOne, common, loading }) => ({
  ...stepApplyOne,
  ...common,
  ...loading,
}), (dispatch) => ({
  dispatchSave(param: any) {
    dispatch({
      type: 'stepApplyOne/save',
      payload: param
    })
  },
  dispatchGetCredit(callback: Function) {
    dispatch({
      type: 'common/getUserCredit',
      payload: {
        callback,
      },
    })
  },
}))
class SetpApplyOne extends Component {

  constructor(props) {
    super(props);
  }

  componentWillReceiveProps(nextProps) {

    const creditLoading = nextProps.effects['common/getUserCredit']

    if (creditLoading) {
      setTimeout(() => {
        utils.showLoadingCenter()
      }, 0)
    } else {
      setTimeout(() => {
        utils.hideLoadingCenter()
      }, 0)
    }
  }

  componentWillMount() {

    // 检查是否已登录
    if (userUtils.isLoginValid()) {
      // 获取url中的 deposit 参数
      const { deposit } = this.$router.params
      this.setState({
        deposit: deposit ? deposit : 10000
      })
    } else {
      const url = '/pages/stepApplyOne/index'
      userUtils.checkIsLogin(url)
    }
  }

  componentDidMount() {
    // 初始化表单
    this.initForm()
  }

  componentWillUnmount() {

  }

  componentDidShow() { }

  componentDidHide() { }

  render() {
    const { form, formValue } = this.props
    // console.log('state.searchOption = ', this.state.searchOption)
    // console.log('searchOption = ', searchOption)

    return (
      <View className='step-apply-one-container'>
        {/* <!-- 头部宣传栏分块 --> */}
        <View className="product-banner">
          <Image src={bannerImg}></Image>
        </View>
        <View className="apply-info-box">
          <ApplyForm form={form} formValue={formValue} dispatchType={'stepApplyOne/updateFormItem'} />
        </View>
        {/* <!-- 底部按钮 --> */}
        <View className="bottom-box">
          <Button onClick={this.submit}>下一步</Button>
        </View>
      </View>
    )
  }

  /**
   * 根据产品对象初始化表单数据
   */
  initForm() {
    const { formValue } = this.props
    const formCopy = Object.assign({}, formValue)

    formCopy.loan_limit = this.state.deposit
    // 默认选中12个月
    formCopy.loan_date_limit = 12

    const that = this
    // 从服务器请求信用数据
    this.props.dispatchGetCredit((userCredit) => {

      // 使用服务器数据初始化form
      Object.assign(formCopy, userCredit)
      // 不使用userCredit的city_code
      if (formCopy.city_code.length > 3) {
        formCopy.city_code = null
      }

      // 联系电话默认使用登录的电话号码
      const userInfo = userUtils.getUserFromLocalStorage()
      if (userInfo) {
        formCopy.tel = userInfo.mobile
      }

      // 加载缓存
      const formCache = productUtils.getApplyFormFromStorage()
      if (formCache) {
        Object.assign(formCopy, formCache)
      }

      that.props.dispatchSave({
        formValue: formCopy
      })
    })
  }

  /**
   * 提交申请表单的方法
   */
  submit = () => {
    const validatorResult = utils.formValidation(this.props.form, this.props.formValue)
    if (!validatorResult.isValidate) {
      Taro.showToast({
        title: validatorResult.msg,
        icon: 'none',
      })
      return
    }

    // 保存表单信息到local storage
    productUtils.saveApplyFormToStorage(this.props.formValue)

    // 跳转到第二步
    Taro.navigateTo({
      url: '/pages/stepApplyTwo/index'
    })
  }

}

// #region 导出注意
//
// 经过上面的声明后需要将导出的 Taro.Component 子类修改为子类本身的 props 属性
// 这样在使用这个子类时 Ts 才不会提示缺少 JSX 类型参数错误
//
// #endregion

export default SetpApplyOne as ComponentClass<PageOwnProps, PageState>
